/**
 * 装饰器模式：
 *   像现有功能添加新功能，同时又不改变其结构设计的设计模式
 *
 *   它是作为现有类的一个包装(wrapper)
 *
 */

function autobind(target, key, descriptor) {
    var fn = descriptor.value;
    var configurable = descriptor.configurable;
    var enumrable = descriptor.enumrable;

    // 返回descriptor
    return {
        configurable: configurable,
        enumrable: enumrable,
        get: function get() {
            // 将该方法绑定this
            var boundFn = fn.bind(this);
            //使用object.defindPropertity重新定义该方法
            Object.defineProperty(this, key, {
                configurable: true,
                writable: true,
                enumerable: false,
                value: boundFn,
            });
            return boundFn;
        },
    };
}

class Person {
    // @autobind
    getPerson() {
        return this;
    }
}

const person = new Person();

// console.log(person.getPerson());

function People() {}

People.prototype.operetion = function () {
    console.log("person实例方法执行");
};

function Decorator() {
    this.compnent = new People();
}

Decorator.prototype.operetion = function () {
    this.compnent.operetion();
    console.log("扩展person.operation()的功能");
};

const decorator = new Decorator();
console.log("decorator方法执行：", decorator.operetion());